=begin pod :kind("Language") :subkind("Language") :category("tutorial")

=TITLE Classes and objects

=SUBTITLE A tutorial about creating and using classes in Raku

X<|OOP>

Raku has a rich built-in syntax for defining and using classes.

A default constructor allows the setting of attributes for the created
object:

=begin code
class Point {
    has Int $.x;
    has Int $.y;
}

class Rectangle {
    has Point $.lower;
    has Point $.upper;

    method area(--> Int) {
        ($!upper.x - $!lower.x) * ( $!upper.y - $!lower.y);
    }
}

# Create a new Rectangle from two Points
my $r = Rectangle.new(lower => Point.new(x => 0, y => 0),
                      upper => Point.new(x => 10, y => 10));

say $r.area(); # OUTPUT: «100␤»
=end code

In the two classes, the default constructor is being used. This
constructor will use named parameters in its invocation: C«Point.new(x =>
0, y => 0)».

You can also provide your own constructor and C<BUILD> implementation.
You need to do it for cases in which there are private attributes that
might need to be populated during object construction, as in the
example below:

=begin code
# Example taken from
# https://medium.freecodecamp.org/a-short-overview-of-object-oriented-software-design-c7aa0a622c83
class Hero {
    has @!inventory;
    has Str $.name;
    submethod BUILD( :$name, :@inventory ) {
        $!name = $name;
        @!inventory = @inventory
    }

    method act {
        return @!inventory.pick;
    }
}
my $hero = Hero.new(:name('Þor'),
                    :inventory(['Mjölnir','Chariot','Bilskirnir']));
say $hero.act;
=end code

In this case, we I<encapsulate> the private attribute C<@!inventory>; but
private instance variables cannot be set by the default constructor, which is
why we add a C<BUILD> submethod that takes care of that.

The following, more elaborate example, shows how a dependency handler might look
in Raku.  It showcases custom constructors, private and public attributes,
L<Submethod|/type/Submethod>s, methods, and various aspects of signatures. It's
not a lot of code, and yet the result is interesting and useful.

=begin code
class Task {
    has      &!callback;
    has Task @!dependencies;
    has Bool $.done;

    # Normally doesn't need to be written
    method new(&callback, *@dependencies) {
        return self.bless(:&callback, :@dependencies);
    }

    # BUILD is the equivalent of a constructor in other languages
    submethod BUILD(:&!callback, :@!dependencies) { }

    method add-dependency(Task $dependency) {
        push @!dependencies, $dependency;
    }

    method perform() {
        unless $!done {
            .perform() for @!dependencies;
            &!callback();
            $!done = True;
        }
    }
}

my $eat =
    Task.new({ say 'eating dinner. NOM!' },
        Task.new({ say 'making dinner' },
            Task.new({ say 'buying food' },
                Task.new({ say 'making some money' }),
                Task.new({ say 'going to the store' })
            ),
            Task.new({ say 'cleaning kitchen' })
        )
    );

$eat.perform();
=end code

In this case, C<BUILD> is needed since we have overridden the default
C<new> constructor. C<bless> is eventually invoking it with the two named
arguments that correspond to the two properties without a default value. With
its signature, C<BUILD> converts the two positionals to the two attributes,
C<&!callback> and C<@!dependencies>, and returns the object (or turns it in to
the next phase, C<TWEAK>, if available).

Declaring C<new> as a C<method> and not as a C<multi method> prevents us
from using the default constructor; this implicit constructor uses the
attributes as named parameters. This is one of the reasons why using
C<new> as a method's name is discouraged. If you need to declare it anyway,
use C<multi method new> if you do not want to disable the default constructor.

C<TWEAK> is the last submethod to be called, and it has the
advantage of having the object properties available without needing to
use the metaobject protocol. It can be used, for instance, to assign
values to instance variables based on the values of other attributes or
instance variables:

=begin code
class Str-with-ID is Str {
    my $counter = 0;
    has Str $.string;
    has Int $.ID;

    submethod TWEAK() {
        $!ID = $counter++;
    }
}

say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «0»
say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «1»
=end code

In this case, we need to compute C<$.ID> from the value of a counter that is a
class variable, C<$counter>, thus we simply assign a value to it and increment
the counter at the same time. Please check also
L<this section on C<TWEAK> in the Object Orientation (OO) document|/language/objects#index-entry-TWEAK>
for the mechanics of object construction.

X<|DESTROY>
X<|submethod DESTROY>

C<DESTROY> is the submethod that gets called when an object is garbage
collected. That is going to happen only if the runtime needs the memory, so we
can't rely on when it's going to happen. In particular, it could happen in the
middle of some running code in a thread, so we must take special care to not
assume any context during that event. We can use it to close any kind of handles
or supplies or delete temporary files that are no longer going to be used.

=begin code
my $in_destructor = 0;

class Foo {
    submethod DESTROY { $in_destructor++ }
}

my $foo;
for 1 .. 6000 {
    $foo = Foo.new();
}

say "DESTROY called $in_destructor times";
=end code

This might print something like C<DESTROY called 5701 times>, but it only kicks
in after we have stomped over former instances of C<Foo> 6000 times. We can't
rely, however, on the order of destruction, for instance.

=head1 Starting with class

X<|class>
X<|classes>

X<|state>
X<|has>
X<|classes,has>
X<|behavior>
X<|classes,behavior>

Raku, like many other languages, uses the C<class> keyword to define a
class. The block that follows may contain arbitrary code, just as with
any other block, but classes commonly contain state and behavior
declarations. The example code includes attributes (state), introduced
through the C<has> keyword, and behaviors, introduced through the C<method>
keyword.

X<|type object>
X<|DEFINITE>
X<|.DEFINITE>

Declaring a class creates a new I<type object> which, by default, is installed
into the current package (just like a variable declared with C<our> scope).
This type object is an "empty instance" of the class. For example, types such as
C<Int> and C<Str> refer to the type object of one of the Raku built-in
classes. The example above uses the class name C<Task> so that other code can
refer to it later, such as to create class instances by calling the C<new>
method.

You can use the C<.DEFINITE> method to find out if what you have is an instance
or a type object:

=begin code
say Int.DEFINITE; # OUTPUT: «False␤» (type object)
say 426.DEFINITE; # OUTPUT: «True␤»  (instance)

class Foo {};
say Foo.DEFINITE;     # OUTPUT: «False␤» (type object)
say Foo.new.DEFINITE; # OUTPUT: «True␤»  (instance)
=end code

You can also use type "smileys" to only accept instances or type objects:

=begin code
multi foo (Int:U) { "It's a type object!" }
multi foo (Int:D) { "It's an instance!"   }
say foo Int; # OUTPUT: «It's a type object!␤»
say foo 42;  # OUTPUT: «It's an instance!␤»
=end code

X<|attributes>
X<|classes,attributes>
X<|encapsulation>
X<|classes,encapsulation>
=head1 State

In the C<Task> class, the first three lines inside the block all
declare attributes (called I<fields> or I<instance storage> in other
languages). Just as a C<my> variable cannot be accessed from outside its
declared scope, attributes are not accessible outside of the class.
This I<encapsulation> is one of the key principles of object oriented design.

The first declaration specifies instance storage for a callback (i.e.,
a bit of code to invoke in order to perform the task that an object
represents):

=for code
has &!callback;

X<|sigils,&>
X<|twigils>
X<|twigils,!>

The C<&> sigil indicates that this attribute represents something invocable.
The C<!> character is a I<twigil>, or secondary sigil. A twigil forms part
of the name of the variable. In this case, the C<!> twigil emphasizes that
this attribute is private to the class.

The second declaration also uses the private twigil:

=for code :preamble<class Task {}>
has Task @!dependencies;

However, this attribute represents an array of items, so it requires the
C<@> sigil. These items each specify a task that must be completed before
the present one is completed. Furthermore, the type declaration on this
attribute indicates that the array may only hold instances of the C<Task>
class (or some subclass of it).

The third attribute represents the state of completion of a task:

=for code
has Bool $.done;

X<|twigils,.>
X<|twigils,accessors>
X<|accessor methods>
X<|classes,accessors>

This scalar attribute (with the C<$> sigil) has a type of C<Bool>. Instead
of the C<!> twigil, the C<.> twigil is used. While Raku does enforce
encapsulation on attributes, it also saves you from writing accessor
methods. Replacing the C<!> with a C<.> both declares a private attribute
and an accessor method named after the attribute. In this case,
both the attribute C<$!done> and the accessor method C<done> are declared.
It's as if you had written:

=begin code
has Bool $!done;
method done() { return $!done }
=end code

Note that this is not like declaring a public attribute, as some languages
allow; you really get I<both> a private attribute and a method,
without having to write the method by hand. You are free instead to write
your own accessor method, if at some future point you need to do something
more complex than returning the value.

X<|traits,is rw>
Note that using the C<.> twigil has created a method that will provide
read-only access to the attribute. If instead the users of this object
should be able to reset a task's completion state (perhaps to perform it
again), you can change the attribute declaration:

=for code
has Bool $.done is rw;

The C<is rw> trait causes the generated accessor method to return a container
so external code can modify the value of the attribute.

You can also supply default values to attributes (which works equally for
those with and without accessors):

=for code
has Bool $.done = False;

The assignment is carried out at object build time. The right-hand side is
evaluated at that time, and can even reference earlier attributes:

=begin code :preamble<class Task {}>
has Task @!dependencies;
has $.ready = not @!dependencies;
=end code

Writable attributes are accessible through writable containers:

=begin code
class a-class {
    has $.an-attribute is rw;
}
say (a-class.new.an-attribute = "hey"); # OUTPUT: «hey␤»
=end code

This attribute can also be accessed using the C<.an-attribute> or
C<.an-attribute()> syntax. See also
L<the C<is rw> trait on classes|/language/typesystem#trait_is_rw> for examples
on how this works on the whole class.

X<|class variables>
A class declaration can also include I<class variables>, which are variables
whose value is shared by all instances, and can be used for things like
counting the number of instantiations or any other shared state.
Class variables use the same syntax as the rest of the attributes, but are
declared as C<my> or C<our>, depending on the scope; C<our> variables will be
shared by subclasses, since they have package scope.

=begin code
class Str-with-ID is Str {
    my $counter = 0;
    our $hierarchy-counter = 0;
    has Str $.string;
    has Int $.ID;

    method TWEAK() {
        $!ID = $counter++;
        $hierarchy-counter++;
    }

}

class Str-with-ID-and-tag is Str-with-ID {
    has Str $.tag;
}

say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «0␤»
say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «1␤»
say Str-with-ID-and-tag.new( string => 'Third', tag => 'Ordinal' ).ID;
# OUTPUT: «2␤»
say $Str-with-ID::hierarchy-counter;       # OUTPUT: «4␤»
=end code

In this case, using C<new> might be the easiest way to initialize the C<$.ID>
field and increment the value of the counter at the same time. C<new>, through
C<bless>, will invoke the default C<BUILD>, assigning the values to their
properties correctly. You can obtain the same effect using C<TWEAK>, which is
considered a better practice by Raku experts. Please check L<the section on
submethods|/language/classtut#index-entry-OOP> for an alternative example on how
to do this. Since C<TWEAK> is called in every object instantiation, it's
incremented twice when creating objects of class C<Str-with-ID-and-tag>; this is
a I<class hierarchy> variable that is shared by all subclasses of
C<Str-with-ID>. Additionally, class variables declared with package scope are
visible via their fully qualified name (FQN), while lexically scoped class
variables are "private".

=head1 Static fields?

Raku has no B<static> keyword. Nevertheless, any class may declare anything
that a module can, so making a scoped variable sounds like a good idea.

=begin code
class Singleton {
    my Singleton $instance;
    method new {!!!}
    submethod instance {
        $instance = Singleton.bless unless $instance;
        $instance;
    }
}
=end code

Class attributes defined by L<my|/syntax/my> or L<our|/syntax/our> may also be
initialized when being declared, however we are implementing the Singleton
pattern here and the object must be created during its first use. It is not 100%
possible to predict the moment when attribute initialization will be executed,
because it can take place during compilation, runtime or both, especially when
importing the class using the L<use|/syntax/use> keyword.

=begin code :preamble<class Foo {}; sub some_complicated_subroutine {}>
class HaveStaticAttr {
    my Foo $.foo = some_complicated_subroutine;
}
=end code

Class attributes may also be declared with a secondary sigil – in a similar
manner to instance attributes – that will generate read-only accessors if the
attribute is to be public.

=head1 Methods

X<|methods>
X<|classes,methods>

While attributes give objects state, methods give objects behaviors. Let's
ignore the C<new> method temporarily; it's a special type of method.
Consider the second method, C<add-dependency>, which adds a new task to a
task's dependency list:

=begin code :skip-test<incomplete code>
method add-dependency(Task $dependency) {
    push @!dependencies, $dependency;
}
=end code

X<|invocant>
In many ways, this looks a lot like a C<sub> declaration. However, there are
two important differences. First, declaring this routine as a method adds it
to the list of methods for the current class, thus any instance of the
C<Task> class can call it with the C<.> method call operator.
Second, a method places its invocant into the special variable C<self>.

The method itself takes the passed parameter – which must be an instance of
the C<Task> class – and C<push>es it onto the invocant's C<@!dependencies>
attribute.

The C<perform> method contains the main logic of the dependency handler:

=begin code :skip-test<incomplete code>
method perform() {
    unless $!done {
        .perform() for @!dependencies;
        &!callback();
        $!done = True;
    }
}
=end code

It takes no parameters, working instead with the object's attributes. First,
it checks if the task has already completed by checking the C<$!done>
attribute. If so, there's nothing to do.

X<|operators,.>
Otherwise, the method performs all of the task's dependencies, using the
C<for> construct to iterate over all of the items in the C<@!dependencies>
attribute. This iteration places each item – each a C<Task> object – into
the topic variable, C<$_>. Using the C<.> method call operator without
specifying an explicit invocant uses the current topic as the invocant.
Thus the iteration construct calls the C<.perform()> method on every C<Task>
object in the C<@!dependencies> attribute of the current invocant.

After all of the dependencies have completed, it's time to perform the
current C<Task>'s task by invoking the C<&!callback> attribute directly;
this is the purpose of the parentheses. Finally, the method sets the
C<$!done> attribute to C<True>, so that subsequent invocations of C<perform>
on this object (if this C<Task> is a dependency of another C<Task>, for
example) will not repeat the task.

X<|! (private methods)>
X<|FQN>
=head2 Private methods

Just like attributes, methods can also be private. Private methods are declared
with a prefixed exclamation mark. They are called with C<self!> followed by the
method's name. In the following implementation of a C<MP3TagData> class to
extract L<ID3v1|https://en.wikipedia.org/wiki/ID3> metadata from an mp3 file,
methods C<parse-data>, C<can-read-format>, and C<trim-nulls> are private
methods while the remaining ones are public methods:

=begin code
class MP3TagData {
    has $.filename where { .IO ~~ :e };

    has Str $.title   is built(False);
    has Str $.artist  is built(False);
    has Str $.album   is built(False);
    has Str $.year    is built(False);
    has Str $.comment is built(False);
    has Int $.genre   is built(False);
    has Int $.track   is built(False);
    has Str $.version is built(False);
    has Str $.type    is built(False) = 'ID3';

    submethod TWEAK {
        with $!filename.IO.open(:r, :bin) -> $fh {
            $fh.seek(-128, SeekFromEnd);
            my $tagdata = $fh.read(128);
            self!parse-data: $tagdata;
            $fh.close;
        }
        else {
            warn "Failed to open file."
        }
    }

    method !parse-data($data) {
        if self!can-read-format($data) {
            my $offset = $data.bytes - 128;

            $!title  = self!trim-nulls: $data.subbuf($offset +  3, 30);
            $!artist = self!trim-nulls: $data.subbuf($offset + 33, 30);
            $!album  = self!trim-nulls: $data.subbuf($offset + 63, 30);
            $!year   = self!trim-nulls: $data.subbuf($offset + 93,  4);

            my Int $track-flag = $data.subbuf($offset + 97 + 28, 1).Int;
            $!track            = $data.subbuf($offset + 97 + 29, 1).Int;

            ($!version, $!comment) = $track-flag == 0 && $!track != 0
                ?? ('1.1', self!trim-nulls: $data.subbuf($offset + 97, 28))
                !! ('1.0', self!trim-nulls: $data.subbuf($offset + 97, 30));

            $!genre = $data.subbuf($offset + 97 + 30, 1).Int;
        }
    }

    method !can-read-format(Buf $data --> Bool) {
        self!trim-nulls($data.subbuf(0..2)) eq 'TAG'
    }

    method !trim-nulls(Buf $data --> Str) {
        $data.decode('utf-8').subst(/\x[0000]+/, '')
    }
}
=end code

To call a private method of another class, the caller has to be trusted by the
callee. A trust relationship is declared with
L<C<trusts>|/language/typesystem#trait_trusts> and the class to be trusted must
already be declared. Calling a private method of another class requires an
instance of that class and the fully qualified name (FQN) of the method. A trust
relationship also allows access to private attributes.

=begin code
class B {...}

class C {
    trusts B;
    has $!hidden = 'invisible';
    method !not-yours () { say 'hidden' }
    method yours-to-use () {
        say $!hidden;
        self!not-yours();
    }
}

class B {
    method i-am-trusted () {
        my C $c.=new;
        $c!C::not-yours();
    }
}

C.new.yours-to-use(); # the context of this call is GLOBAL, and not trusted by C
B.new.i-am-trusted();
=end code

Trust relationships are not subject to inheritance. To trust the global
namespace, the pseudo package C<GLOBAL> can be used.

X<|constructors>
=head1 Constructors

Raku is rather more liberal than many languages in the area of
constructors. A constructor is anything that returns an instance of the
class. Furthermore, constructors are ordinary methods. You inherit a
default constructor named C<new> from the base class C<Mu>, but you are
free to override C<new>, as this example does:

=begin code
method new(&callback, *@dependencies) {
    return self.bless(:&callback, :@dependencies);
}
=end code

X<|objects,bless>
X<|bless>

The biggest difference between constructors in Raku and constructors in
languages such as C# and Java is that rather than setting up state on a
somehow already magically created object, Raku constructors create the
object themselves. The easiest way to do this is by calling the
L<bless|/routine/bless> method, also inherited from L<Mu|/type/Mu>.
The C<bless> method expects a set of named parameters to provide the initial
values for each attribute.

The example's constructor turns positional arguments into named arguments,
so that the class can provide a nice constructor for its users. The first
parameter is the callback (the thing which will execute the task). The rest
of the parameters are dependent C<Task> instances. The constructor captures
these into the C<@dependencies> slurpy array and passes them as named
parameters to C<bless> (note that C<:&callback> uses the name of the
variable – minus the sigil – as the name of the parameter).

X<|BUILD>
Private attributes really are private. This means that C<bless> is not
allowed to bind things to C<&!callback> and C<@!dependencies> directly. To
do this, we override the C<BUILD> submethod, which is called on the brand
new object by C<bless>:

=begin code :preamble<has &.callback; has @.dependencies;>
submethod BUILD(:&!callback, :@!dependencies) { }
=end code

Since C<BUILD> runs in the context of the newly created C<Task> object, it
is allowed to manipulate those private attributes. The trick here is that
the private attributes (C<&!callback> and C<@!dependencies>) are being used
as the bind targets for C<BUILD>'s parameters. Zero-boilerplate
initialization! See L<objects|/language/objects#Object_construction> for
more information.

The C<BUILD> method is responsible for initializing all attributes and must
also handle default values:

=begin code
has &!callback;
has @!dependencies;
has Bool ($.done, $.ready);
submethod BUILD(
        :&!callback,
        :@!dependencies,
        :$!done = False,
        :$!ready = not @!dependencies,
    ) { }
=end code

See L<Object Construction|/language/objects#Object_construction> for more
options to influence object construction and attribute initialization.

=head1 Consuming our class

After creating a class, you can create instances of the class. Declaring a
custom constructor provides a simple way of declaring tasks along with their
dependencies. To create a single task with no dependencies, write:

=for code :preamble<class Task {}>
my $eat = Task.new({ say 'eating dinner. NOM!' });

An earlier section explained that declaring the class C<Task> installed a
type object in the namespace. This type object is a kind of "empty
instance" of the class, specifically an instance without any state. You can
call methods on that instance, as long as they do not try to access any
state; C<new> is an example, as it creates a new object rather than
modifying or accessing an existing object.

Unfortunately, dinner never magically happens. It has dependent tasks:

=begin code :preamble<class Task {}>
my $eat =
    Task.new({ say 'eating dinner. NOM!' },
        Task.new({ say 'making dinner' },
            Task.new({ say 'buying food' },
                Task.new({ say 'making some money' }),
                Task.new({ say 'going to the store' })
            ),
            Task.new({ say 'cleaning kitchen' })
        )
    );
=end code

Notice how the custom constructor and the sensible use of whitespace makes
task dependencies clear.

Finally, the C<perform> method call recursively calls the C<perform> method
on the various other dependencies in order, giving the output:

=begin code :lang<output>
making some money
going to the store
buying food
cleaning kitchen
making dinner
eating dinner. NOM!
=end code

=head1 Inheritance

X<|classes, inheritance>

Object Oriented Programming provides the concept of inheritance as one of
the mechanisms for code reuse. Raku supports the ability for one
class to inherit from one or more classes. When a class inherits from
another class it informs the method dispatcher to follow the inheritance
chain to look for a method to dispatch. This happens both for standard
methods defined via the C<method> keyword and for methods generated through
other means, such as attribute accessors.

=begin code
class Employee {
    has $.salary;
}

class Programmer is Employee {
    has @.known_languages is rw;
    has $.favorite_editor;

    method code_to_solve( $problem ) {
        return "Solving $problem using $.favorite_editor in "
        ~ $.known_languages[0];
    }
}
=end code

Now, any object of type Programmer can make use of the methods and accessors
defined in the Employee class as though they were from the Programmer class.

=begin code :preamble<class Programmer {}>
my $programmer = Programmer.new(
    salary => 100_000,
    known_languages => <Raku Perl Erlang C++>,
    favorite_editor => 'vim'
);

say $programmer.code_to_solve('halting problem'),
    " will get \$ {$programmer.salary()}";
# OUTPUT: «Solving halting problem using vim in Raku will get $100000␤»
=end code

=head2 Overriding inherited methods

Of course, classes can override methods and attributes defined by parent
classes by defining their own. The example below demonstrates the C<Baker>
class overriding the C<Cook>'s C<cook> method.

=begin code :preamble<class Employee {}>
class Cook is Employee {
    has @.utensils  is rw;
    has @.cookbooks is rw;

    method cook( $food ) {
        say "Cooking $food";
    }

    method clean_utensils {
        say "Cleaning $_" for @.utensils;
    }
}

class Baker is Cook {
    method cook( $confection ) {
        say "Baking a tasty $confection";
    }
}

my $cook = Cook.new(
    utensils  => <spoon ladle knife pan>,
    cookbooks => 'The Joy of Cooking',
    salary    => 40000
);

$cook.cook( 'pizza' );       # OUTPUT: «Cooking pizza␤»
say $cook.utensils.raku;     # OUTPUT: «["spoon", "ladle", "knife", "pan"]␤»
say $cook.cookbooks.raku;    # OUTPUT: «["The Joy of Cooking"]␤»
say $cook.salary;            # OUTPUT: «40000␤»

my $baker = Baker.new(
    utensils  => 'self cleaning oven',
    cookbooks => "The Baker's Apprentice",
    salary    => 50000
);

$baker.cook('brioche');      # OUTPUT: «Baking a tasty brioche␤»
say $baker.utensils.raku;    # OUTPUT: «["self cleaning oven"]␤»
say $baker.cookbooks.raku;   # OUTPUT: «["The Baker's Apprentice"]␤»
say $baker.salary;           # OUTPUT: «50000␤»
=end code

Because the dispatcher will see the C<cook> method on C<Baker> before it
moves up to the parent class the C<Baker>'s C<cook> method will be called.

To access methods in the inheritance chain, use
L<re-dispatch|/language/functions#Re-dispatching> or the
L<MOP|/type/Metamodel::ClassHOW#method_can>.

=head2 Multiple inheritance

As mentioned before, a class can inherit from multiple classes. When a
class inherits from multiple classes the dispatcher knows to look at both
classes when looking up a method to search for. Raku uses the
L<C3 algorithm|https://en.wikipedia.org/wiki/C3_linearization> to linearize
multiple inheritance hierarchies, which is better than depth-first search
for handling multiple inheritance.

=begin code :preamble<class Programmer {}; class Cook {}>
class GeekCook is Programmer is Cook {
    method new( *%params ) {
        push( %params<cookbooks>, "Cooking for Geeks" );
        return self.bless(|%params);
    }
}

my $geek = GeekCook.new(
    books           => 'Learning Raku',
    utensils        => ('stainless steel pot', 'knife', 'calibrated oven'),
    favorite_editor => 'MacVim',
    known_languages => <Raku>
);

$geek.cook('pizza');
$geek.code_to_solve('P =? NP');
=end code

Now all the methods made available to the Programmer and the Cook classes
are available from the GeekCook class.

While multiple inheritance is a useful concept to know and occasionally use,
it is important to understand that there are more useful OOP concepts.  When
reaching for multiple inheritance it is good practice to consider whether
the design wouldn't be better realized by using roles, which are generally
safer because they force the class author to explicitly resolve conflicting
method names. For more information on roles, see
L<Roles|/language/objects#Roles>.

=head2 The X<C<also>|also declarator> declarator

Classes to be inherited from can be listed in the class declaration body by
prefixing the C<is> trait with C<also>. This also works for the role
composition trait C<does>.

=begin code :preamble<class Programmer {}; class Cook {}>
class GeekCook {
    also is Programmer;
    also is Cook;
    # ...
}

role A {};
role B {};
class C {
    also does A;
    also does B;
    # ...
}
=end code

=head1 Introspection

Introspection is the process of gathering information about some objects in
your program, not by reading the source code, but by querying the object (or
a controlling object) for some properties, such as its type.

Given an object C<$o> and the class definitions from the previous sections,
we can ask it a few questions:

=begin code :preamble<class Programmer {}; class Employee {}; class GeekCook {}>
my Programmer $o .= new;
if $o ~~ Employee { say "It's an employee" };
say $o ~~ GeekCook ?? "It's a geeky cook" !! "Not a geeky cook";
say $o.^name;
say $o.raku;
say $o.^methods(:local)».name.join(', ');
=end code

The output might look like this:

=begin code :lang<output>
It's an employee
Not a geeky cook
Programmer
Programmer.new(known_languages => ["Perl", "Python", "Pascal"],
        favorite_editor => "gvim", salary => "too small")
code_to_solve, known_languages, favorite_editor
=end code

The first two tests each smartmatch against a class name. If the object is
of that class, or of an inheriting class, it returns C<True>. So the object in
question is of class C<Employee> or one that inherits from it, but not
C<GeekCook>.

The call C<$o.^name> tells us the type of C<$o>; in this case C<Programmer>.

C<$o.raku> returns a string that can be executed as Raku code, and
reproduces the original object C<$o>. While this does not work perfectly in
all cases, it is very useful for debugging simple objects.
N<For example, closures cannot easily be reproduced this way; if you
don't know what a closure is don't worry. Also current implementations have
problems with dumping cyclic data structures this way, but they are expected
to be handled correctly by C<.raku> at some point.>

The syntax of calling a method with C<.^> instead of a single dot means that
it is actually a method call on its I<metaclass>, which is a class managing
the properties of the C<Programmer> class – or any other class you are
interested in. This metaclass enables other ways of introspection too:

=for code :preamble<my $o>
say $o.^attributes.join(', ');
say $o.^parents.map({ $_.^name }).join(', ');

Finally C<$o.^name> calls the C<name> method on the metaobject, which
unsurprisingly returns the class name.

Given an object C<$mp3> and the C<MP3TagData> class definition from the section
L<Private methods|/language/classtut#Private_methods>, we can inquire about its
public methods with C<.^methods>:

=begin code :skip-test<compile time error>
my $mp3 = MP3TagData.new(filename => 'football-head.mp3');
say $mp3.^methods(:local);
# OUTPUT: (TWEAK filename title artist album year comment genre track version
# type Submethod+{is-hidden-from-backtrace}.new)
=end code

X<|^methods>
C<$mp3.^methods(:local)> produces a list of L<Method|/type/Method>s that can be
called on C<$mp3>. The C<:local> named argument limits the returned methods to
those defined in the C<MP3TagData> class and excludes the inherited methods;
C<MP3TagData> inherits from no class, so providing C<:local> makes no difference.

X<|classes,find_method>
To check if a type object (or an instance object) implements a certain public
method, use the L<C<.^find-method>|/routine/find_method> metamethod, which
returns the method object if it exists. Otherwise, it returns L<C<Mu>|/type/Mu>.

=begin code :skip-test<compile time error>
say $mp3.^find_method('name');   # OUTPUT: «(Mu)␤»
say $mp3.^find_method('artist'); # OUTPUT: «artist␤»
=end code

X<|classes,private_methods>
X<|classes,find_private_methods>
Type objects can also be introspected for its private methods. However, public
and private methods don't use the same APIs, and thus different metamethods
must be used: L<C<.^private_methods>|/routine/private_methods> and
L<C<.^find_private_method>|/routine/find_private_method>.

=begin code :skip-test<compile time error>
say $mp3.^private_methods;                     # OUTPUT: «(parse-data can-read-format trim-nulls)␤»
say $mp3.^find_private_method('parse-data');   # OUTPUT: «parse-data␤»
say $mp3.^find_private_method('remove-nulls'); # OUTPUT: «(Mu)»
=end code

Introspection is very useful for debugging and for learning the language
and new libraries. When a function or method returns an object you don't
know about, by finding its type with C<.^name>, seeing a construction recipe
for it with C<.raku>, and so on, you'll get a good idea of what its return
value is. With C<.^methods>, you can learn what you can do with the class.

But there are other applications too. For instance, a routine that serializes
objects to a bunch of bytes needs to know the attributes of that object,
which it can find out via introspection.

=head2 X<Overriding default gist method>

Some classes might need its own version of C<gist>, which overrides the terse
way it is printed when called to provide a default representation of the class.
For instance, L<exceptions|/language/exceptions#Uncaught_exceptions> might want
to write just the C<payload> and not the full object so that it is clearer what
to see what's happened. However, this isn't limited to exceptions; you can
do that with every class:

=begin code
class Cook {
    has @.utensils  is rw;
    has @.cookbooks is rw;

    method cook( $food ) {
        return "Cooking $food";
    }

    method clean_utensils {
        return "Cleaning $_" for @.utensils;
    }

    multi method gist(Cook:U:) { '⚗' ~ self.^name ~ '⚗' }
    multi method gist(Cook:D:) {
        '⚗ Cooks with ' ~ @.utensils.join( " ‣ ") ~ ' using '
          ~ @.cookbooks.map( "«" ~ * ~ "»").join( " and ") }
}

my $cook = Cook.new(
    utensils => <spoon ladle knife pan>,
    cookbooks => ['Cooking for geeks','The French Chef Cookbook']);

say Cook.gist; # OUTPUT: «⚗Cook⚗»
say $cook.gist; # OUTPUT: «⚗ Cooks with spoon ‣ ladle ‣ knife ‣ pan using «Cooking for geeks» and «The French Chef Cookbook»␤»
=end code

Usually you will want to define two methods, one for the class and another for
class instances; in this case, the class method uses the alembic symbol, and the
instance method, defined below it, aggregates the data we have on the cook to show
it in a narrative way.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
